-- This file is part of SUIT, copyright (c) 2016 Matthias Richter

local BASE = (...):match('(.-)[^%.]+$')

local theme = {}
theme.cornerRadius = 4

theme.color = {
	normal   = {bg = { 0.25, 0.25, 0.25 , 0.25}, fg = {0.9,0.9,0.9}},
	hovered  = {bg = { 0.19,0.6,0.73,0.5}, fg = {1,1,1}},
	active   = {bg = {1,0.6,  0,1}, fg = {1,1,1}}
}

-- HELPER
function theme.getColorForState(opt)
	local s = (opt.state == "normal" and opt.toggle and "active") or opt.state or "normal"
	return (opt.color and opt.color[opt.state]) or theme.color[s]
end


function theme.drawBox(x,y,w,h, colors, cornerRadius)
	colors = colors or theme.getColorForState(opt)
	cornerRadius = cornerRadius or theme.cornerRadius
	w = math.max(cornerRadius/2, w)
	if h < cornerRadius/2 then
		y,h = y - (cornerRadius - h), cornerRadius/2
	end
    love.graphics.setBlendMode("alpha")
	love.graphics.setColor(colors.bg)
	love.graphics.rectangle('fill', x,y, w,h, cornerRadius)
	love.graphics.setColor(colors.fg)
	love.graphics.rectangle('line', x,y, w,h, cornerRadius)
end



function theme.drawPolygon(polygon,colors) 
	colors = colors or theme.getColorForState(opt)
	
    
    local function myStencilFunction()
        love.graphics.polygon("fill",polygon)
    end
    love.graphics.stencil(myStencilFunction,"replace",1)
    love.graphics.setStencilTest("equal", 1)
    if theme.bgTexture then
        love.graphics.setBlendMode("replace")
        love.graphics.draw(theme.bgTexture)
    end
    love.graphics.setBlendMode("alpha")
	love.graphics.setLineWidth(3)
    love.graphics.setColor(colors.bg)
    love.graphics.polygon("fill",polygon)
    love.graphics.setColor(colors.fg)
    love.graphics.polygon("line",polygon)
	love.graphics.setLineWidth(1)
	love.graphics.setStencilTest()
end


function theme.getVerticalOffsetForAlign(valign, font, h)
	if valign == "top" then
		return 0
	elseif valign == "bottom" then
		return h - font:getHeight(text)
	end

	return (h - font:getHeight(text)) / 2
end

-- WIDGET VIEWS
function theme.Label(text, opt, x,y,w,h)
	local c = theme.getColorForState(opt)
	if opt.drawborder then
        if opt.polygon then
            theme.drawPolygon(opt.polygon,c)
        else
            theme.drawBox(x,y,w,h, c, opt.cornerRadius)
        end
    end
	y = y + theme.getVerticalOffsetForAlign(opt.valign, opt.font, h)

	love.graphics.setColor((opt.color and opt.color.normal or {}).fg or theme.color.normal.fg)
	love.graphics.setFont(opt.font)
	love.graphics.printf(text, x+2, y, w-4, opt.align or "center")
end

function theme.Button(text, opt, x,y,w,h)
	local c = theme.getColorForState(opt)
	if opt.polygon then
		theme.drawPolygon(opt.polygon,c)
	else
		theme.drawBox(x,y,w,h, c, opt.cornerRadius)
	end
	love.graphics.setColor(c.fg)
	love.graphics.setFont(opt.font)

	y = y + theme.getVerticalOffsetForAlign(opt.valign, opt.font,h)
	local fw = opt.font:getWidth(text)
	if string.find(text,"\n") then
		local lineCount = math.ceil(fw/w)
		love.graphics.printf(text, x+2, y - 0.5*opt.font:getHeight()*(lineCount), w-4, opt.align or "center")
	else
		love.graphics.printf(text, x+2, y , w-4, opt.align or "center")
	end
	
end

function theme.Panel(opt,x,y,w,h)
	theme.drawBox(x,y,w,h, theme.color.normal, opt.cornerRadius)
end

function theme.Checkbox(chk, opt, x,y,w,h)
	local c = theme.getColorForState(opt)
	local th = opt.font:getHeight()

	theme.drawBox(x+h/10,y+h/10,h*.8,h*.8, c, opt.cornerRadius)
	love.graphics.setColor(c.fg)
	if chk.checked then
		love.graphics.setLineStyle('smooth')
		love.graphics.setLineWidth(5)
		love.graphics.setLineJoin("bevel")
		love.graphics.line(x+h*.2,y+h*.55, x+h*.45,y+h*.75, x+h*.8,y+h*.2)
	end

	if chk.text then
		love.graphics.setFont(opt.font)
		y = y + theme.getVerticalOffsetForAlign(opt.valign, opt.font, h)
		love.graphics.printf(chk.text, x + h, y, w - h, opt.align or "left")
	end
end

function theme.Slider(fraction, opt, x,y,w,h)
	local xb, yb, wb, hb -- size of the progress bar
	local r =  math.min(w,h) / 2.1
	if opt.vertical then
		x, w = x + w*.25, w*.5
		xb, yb, wb, hb = x, y+h*(fraction), w, h*fraction
	else
		y, h = y + h*.25, h*.5
		xb, yb, wb, hb = x,y, w*fraction, h
	end

	local c = theme.getColorForState(opt)
	theme.drawBox(x,y,w,h, c, opt.cornerRadius)
	--theme.drawBox(xb,yb,wb,hb, {bg=c.fg,fg=c.fg}, opt.cornerRadius)

	--if opt.state ~= nil and opt.state ~= "normal" then
		love.graphics.setColor((opt.color and opt.color.active or {}).fg or theme.color.active.fg)
		if opt.vertical then
			love.graphics.circle('fill', x+wb/2, yb, r)
		else
			love.graphics.circle('fill', x+wb, yb+hb/2, r)
		end
	--end
end
local utf8 = require 'utf8'
--local kido = require ("editor/kido")
function theme.Input(input, opt, x,y,w,h)
    local lineCount = #input.lines
    if opt.autoHeight then
        h = math.max((opt.font:getHeight()+1)*lineCount + 4,h)
    end
    opt.offset_y = opt.offset_y or 0
    local lh = (opt.font:getHeight()+1)*lineCount + 4
    
    opt.offset_y = math.min(lh-h,math.max(opt.offset_y,0))
    opt.offset_y = opt.offset_y<0 and 0 or opt.offset_y
    input.text_draw_offset = input.text_draw_offset or 0
    x = x + 2
	w = w - 2
    h = h - 2
    theme.drawBox(x,y,w,h, (opt.color and opt.color.normal) or theme.color.normal, opt.cornerRadius)
	-- set scissors
	
	--[[
	local sx, sy, sw, sh = love.graphics.getScissor()
	if sx then
        local l = math.max(sx,x-1)
        local r = math.min(sx+sw,x-1+w+2)
        local t = math.max(sy,y)
        local b = math.min(sy+sh,y+h)
        love.graphics.setScissor(l,t,r-l<0 and 0 or r-l,b-t<0 and 0 or b-t)
    else
        love.graphics.setScissor(x-1,y,w+2 < 0 and 0 or w+2,h<0 and 0 or h)
    end]]
	local th = opt.font:getHeight()
	
    if opt.linenum then
        love.graphics.setFont(opt.font)
        love.graphics.setColor(0.5,0.5,1,0.8)
        for i,line in ipairs(input.lines) do
            love.graphics.printf(i, 
                x, y+ 2+ (i-1)*(th+1)-opt.offset_y,20,"center")
        end
        x = x + 22
        w = w - 22
    else
        x = x + 2
    end
    
	
	love.graphics.setColor((opt.color and opt.color.normal and opt.color.normal.fg) or theme.color.normal.fg)
	love.graphics.setFont(opt.font)
    
    for i,line in ipairs(input.lines) do
    	if opt.password then
	        local len = input.text:sub(line.sol,line.eol):len()
	        love.graphics.print(string.rep("*",len), 
	            x, y+ 2+ (i-1)*(th+1)-opt.offset_y)
	    else
	    	love.graphics.print(input.text:sub(line.sol,line.eol), 
	            x, y+ 2+ (i-1)*(th+1)-opt.offset_y)
	    end
    end
    if opt.highlight then 
        love.graphics.setColor(0.8,0.1,0.3)
        for i,line in ipairs(input.lines) do
            
            local str = input.text:sub(line.sol,line.eol)
            str = " "..str.." "
            for cn,en in pairs(kido.c) do
                local s,e = 1,1
                repeat
                    s,e = string.find(str,"[%w%s%p]"..cn.."[%w%s%p]",e)
                    
                    if s then
                        --print(s,e,string.sub(str,s,e),str)
                        local l = s == 2 and 0 or 
                            opt.font:getWidth(string.sub(str,2,s))
                        love.graphics.print(cn,x + l,
                            y+ 2+ (i-1)*(th+1)-opt.offset_y)
                    end
                until not s
            end
            
            for pe,ee in pairs(kido.ee) do
                local s,e
                repeat 
                    s,e = string.find(str,"%W("..pe..")%W",e)
                    if s then
                        local l = opt.font:getWidth(string.sub(str,1,s - 1))
                        love.graphics.print(ee,x + l,
                            y+ 2+ (i-1)*(th+1)-opt.offset_y)
                    end
                until not s
            end
        end
    end
	-- cursor
    love.graphics.setColor(1,1,1)
	if opt.hasKeyboardFocus and (love.timer.getTime() % 1) > .5 then
		love.graphics.line(x + opt.cursor_posx, y + opt.cursor_posy-opt.offset_y,
		                   x + opt.cursor_posx, y + th+ opt.cursor_posy-opt.offset_y)
        if u32 then
	        u32.SetCaretPos(x + opt.cursor_posx, 
	            y + 1 + opt.cursor_posy-opt.offset_y)
	    end
	end
    love.graphics.setScissor(sx,sy,sw,sh)
	-- reset scissor
	
end

return theme